V následujícím grafu jsou pro příklad zvýrazněny volatilní pohyby:
Volatilní pohyb je jedna z možností, jak sledovat a analyzovat tržní pohyby, které jsou založeny na emocích. Pokud se cena určité komodity rychle mění, vyvolává to v obchodnících silné emoce. Pokud např. cena nemovitostí během roku vzroste o 100% a má tendenci dále růst, všimnou si toho všichni a ti, co by s koupí nemovitosti otálely, si velmi rychle uspíší ji koupit za aktuální cenu, protože když budou čekat, mohla by cena být někde opravdu vysoko a oni by si už nemohli dovolit nemovitost koupit. A čím rychleji cena stoupá, tím více lidí se nákup snaží uspíšit. Otázka zní:
"Je dobré nakupovat s nimi, nebo je lepší jim danou věc prodat"?
Budu vycházet ze zdarma dostupných EOD (End Of Day) dat trhu SPY (ETF, kopírující hlavní americký akciový index S&P 500), který můžu stáhnout z yahoo finance pomocí pandas-datareader
. Online graf je možné vidět na https://finance.yahoo.com/chart/SPY.
In [1]:
import pandas as pd
import pandas_datareader.data as web
import datetime
start = datetime.datetime(2015, 1, 1)
end = datetime.datetime(2018, 8, 31)
spy_data = web.DataReader('SPY', 'yahoo', start, end)
spy_data = spy_data.drop(['Volume', 'Adj Close'], axis=1) # sloupce 'Volume' a 'Adj Close' nebudu potřebovat
spy_data.tail()
Out[1]:
Každý řádek představuje cenu pro daný den a to nejvyšší (High), nejnižší (Low), otevírací (Open - začátek dne) a uzavírací (Close - konec dne). Volatilní pohyb pro daný den pak vidím v grafu na první pohled jako výrazné velké svíce (viz. graf 1). Abych je mohl automaticky v mém analytickém softwaru (python - pandas) označit, definuji volatilní svíce pomocí pravidla například jako:
Velikost změny ceny musí být větší než 4 předchozí svíce
K tomuto zjištění musím vypočítat velikost vzdálenosti pro jednotlivé svíce $Close-Open$. Pandas mi tuhle práci velmi pěkně usnadní:
In [2]:
spy_data['C-O'] = spy_data['Close'] - spy_data['Open']
spy_data.tail()
Out[2]:
Nyní znám přesnou změnu ceny každý den. Abych mohl porovnávat velikosti, aniž by mi záleželo na tom, zda se daný den cena propadla, nebo stoupla, aplikuji absolutní hodnotu.
In [3]:
spy_data['Abs(C-O)'] = spy_data['C-O'].abs()
spy_data.tail()
Out[3]:
Volatilní svíce identifikuji pomocí funkcionality rolling
a funkce apply
. Funkcionalita rolling
umožnuje rozdělit pandas DataFrame na jednotlivé menší "okna", které bude předávat postupně funkci apply
v parametru. Tzn. že v následujícím kódu se provede výpočet funkce is_bigger
pro každý řádek dat uložených v spy_data
. Do parametru rows
se bude postupně vkládat výřez dat, obsahující 4 řádky (aktuální počátaný řádek + 3 řádky předchozí). Jako výsledek funkce is_bigger
bude hodnota, zda je aktuálně počítaný řádek volatilnější, než 4 předchozí.
In [4]:
def is_bigger(rows):
result = rows[-1] > rows[:-1].max() # rows[-1] - poslední hodnota je větší než maximum z předchozích
return result
spy_data['VolBar'] = spy_data['Abs(C-O)'].rolling(4).apply(is_bigger,raw=True)
spy_data.tail(10)
Out[4]:
Které svíce jsou volatilnější, než 4 předchozí, si zobrazím pomocí jednoduché selekce, kde ve sloupečku VolBar == 1
.
In [5]:
spy_data[spy_data['VolBar'] == 1].tail()
Out[5]:
Příště se zaměřím na to, jak jednoduše tyhle volatilní úsečky analyzovat.